Conectando com o Brasil — API de Serviços do IBGE
Aprenda a dialogar com os dados oficiais do país, requisitando informações de localidades, malhas territoriais, estatísticas econômicas e estações geodésicas diretamente do Python.
Você vai aprender a
- ▹Descobrir endpoints da API do IBGE e montar URLs dinâmicas.
- ▹Transformar respostas JSON em tabelas Pandas prontas para análise.
- ▹Trazer GeoJSONs de malhas territoriais para mapas Folium.
- ▹Criar um laboratório integrado combinando múltiplos serviços.
1. Por que consultar a API do IBGE?
Até aqui, trabalhamos com dados coletados manualmente ou armazenados em arquivos locais. Mas manter planilhas atualizadas para todo o Brasil é inviável. A API de Serviços do IBGE funciona como um balcão digital em que podemos solicitar apenas o que importa: um recorte estatístico, a lista de municípios de um estado, ou a geometria de uma malha municipal para cartografia.
Ao incorporar o IBGE às suas rotinas, você:
- automatiza buscas que seriam repetitivas e sujeitas a erro humano;
- garante que os dados consultados são oficiais e atualizados;
- reduz o tamanho de arquivos trafegados, pedindo só o necessário para a análise.
2. Como a API se organiza
Tipos de serviços disponíveis
- Localidades: nomes, códigos e hierarquia (UF → mesorregiões → municípios).
- Malhas territoriais: arquivos GeoJSON simplificados para municípios, estados e regiões.
- Séries estatísticas (SIDRA): indicadores econômicos e demográficos em múltiplos níveis.
- Rede geodésica: estações GNSS e marés com coordenadas e metadados.
Dica do professor
Comece explorando a API direto no navegador. Copie a URL-base, acrescente os parâmetros sugeridos pela documentação e verifique a resposta JSON. Só depois leve essa string para o Python, tornando seu script mais seguro e previsível.
Atenção
Alguns endpoints exigem informar o parâmetro formato (ex.: application/json ou application/vnd.geo+json) e limites de resolução. Sem isso, você pode receber HTML ou arquivos zipados. Sempre confira a documentação específica do serviço escolhido.
3. Sua primeira requisição em Python
O pacote requests simplifica a comunicação HTTP. No exemplo abaixo, buscamos a lista de UFs e ressaltamos os cinco primeiros resultados.
import requests
URL_ESTADOS = "https://servicodados.ibge.gov.br/api/v1/localidades/estados"
print("Consultando estados na API do IBGE...")
try:
resposta = requests.get(URL_ESTADOS, timeout=10)
resposta.raise_for_status()
estados = resposta.json()
print(f"Foram encontrados {len(estados)} estados.")
print("\nPrimeiros resultados:")
for estado in estados[:5]:
print(f"- {estado['nome']} ({estado['sigla']})")
except requests.exceptions.RequestException as erro:
print(f"Falha na requisição: {erro}")
A função raise_for_status() evita que códigos 404 ou 500 passem despercebidos. Combine com timeout para que seu script não fique preso caso a rede oscile.
4. Explorando os principais endpoints
4.1 Localidades
Os códigos oficiais dos municípios são indispensáveis para cruzar bases. A consulta abaixo retorna todas as cidades de Santa Catarina (UF 42) e extrai o identificador de Florianópolis.
import requests
UF_CODE = "42" # Santa Catarina
URL_MUNICIPIOS = f"https://servicodados.ibge.gov.br/api/v1/localidades/estados/{UF_CODE}/municipios"
municipios = requests.get(URL_MUNICIPIOS, timeout=10).json()
print(f"{len(municipios)} municípios retornados.")
codigo_floripa = next(
municipio["id"]
for municipio in municipios
if municipio["nome"] == "Florianópolis"
)
print(f"Código IBGE da capital: {codigo_floripa}")
4.2 Malhas territoriais
As malhas municipais disponibilizadas pelo IBGE são distribuídas em arquivos .zip contendo shapefiles. No exemplo abaixo, baixamos a coleção de Santa Catarina, filtramos Joinville e exibimos a geometria no Folium.
import io
import zipfile
import folium
import geopandas as gpd
import requests
URL_MALHA_SC = (
"https://geoftp.ibge.gov.br/organizacao_do_territorio/"
"malhas_territoriais/malhas_municipais/municipio_2022/UFs/SC/"
"SC_Municipios_2022.zip"
)
print("Baixando malha municipal 2022 (SC)...")
resposta = requests.get(URL_MALHA_SC, timeout=30)
resposta.raise_for_status()
with zipfile.ZipFile(io.BytesIO(resposta.content)) as arquivo_zip:
arquivo_zip.extractall("malha_sc")
gdf = gpd.read_file("malha_sc/SC_Municipios_2022.shp")
joinville = gdf[gdf["NM_MUN"] == "Joinville"]
centro = joinville.geometry.centroid.iloc[0]
mapa = folium.Map(location=[centro.y, centro.x], zoom_start=10)
folium.GeoJson(joinville.to_json(), name="Joinville").add_to(mapa)
folium.LayerControl().add_to(mapa)
mapa.show_in_browser()
Após conferir o mapa, substitua show_in_browser() por save("joinville.html") para compartilhar o resultado. Lembre-se de remover a pasta temporária malha_sc quando não for mais necessária.
4.3 Estatísticas (SIDRA)
As tabelas do SIDRA contêm indicadores econômicos e demográficos. A URL combina agregados, períodos, variáveis e o recorte geográfico.
import requests
import pandas as pd
TABELA = "5938" # PIB dos Municípios
VARIAVEL = "37" # PIB per capita
UF_CODE = "42" # Santa Catarina
url_pib = (
f"https://servicodados.ibge.gov.br/api/v3/agregados/{TABELA}/periodos/2021/"
f"variaveis/{VARIAVEL}?localidades=N6[N3[{UF_CODE}]]&classificacao=2[all]"
)
resposta = requests.get(url_pib, timeout=20).json()
serie = resposta[0]["resultados"][0]["series"][0]["serie"]
pib_df = (
pd.DataFrame([
{"codigo_municipio": codigo, "pib_per_capita": float(valor)}
for codigo, valor in serie.items()
])
.sort_values("pib_per_capita", ascending=False)
)
print(pib_df.head())
Alguns indicadores retornam strings com separador decimal. Converta-os para float ou Decimal antes de calcular estatísticas.
4.4 Rede geodésica
Estações GNSS permitem validações geodésicas e calibração de levantamentos. O endpoint aceita filtros por UF, tipo de estação e situação operacional.
import requests
URL_GNSS = "https://servicodados.ibge.gov.br/api/v1/geodesia/estacoes"
PARAMS = {"uf": "SC"}
estacoes = requests.get(URL_GNSS, params=PARAMS, timeout=15).json()
print(f"Estacoes encontradas: {len(estacoes)}")
for estacao in estacoes[:3]:
print("-", estacao["identificador"], estacao["nome"], estacao["situacao"])
Curiosidade: Por que algumas URLs têm N6[N3[42]]?
A sintaxe indica a combinação de níveis territoriais: N representa o nível geográfico (N1 = Brasil, N2 = Grandes Regiões, N3 = UFs, N6 = Municípios). Já o valor entre colchetes define o recorte. Portanto, N6[N3[42]] significa “todos os municípios (N6) pertencentes à UF 42 (Santa Catarina)”.
5. Exercício rápido
- Monte uma função que receba o nome da UF e retorne um
DataFramecom o código e o nome de todos os municípios daquela unidade federativa. - Utilizando o código de um município, baixe sua malha em GeoJSON e exiba no Folium. Experimente variar o parâmetro
resolucao. - Combine os dados de PIB per capita com a malha municipal e crie um mapa coroplético simples.
- Liste as estações GNSS que estão “Ativas” e exporte o resultado para CSV.
Conclusão
Integrar a API do IBGE ao seu fluxo elimina tarefas manuais, garante dados auditáveis e prepara terreno para visualizações dinâmicas. O próximo passo é transformar essas respostas em relatórios, painéis ou mapas que contem histórias convincentes.